import datetime
import random
from django_redis import get_redis_connection
from django.http import HttpResponse
from django.views import View
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets
from rest_framework.authentication import BasicAuthentication, SessionAuthentication
from rest_framework.decorators import action, api_view, authentication_classes, permission_classes
from rest_framework.filters import OrderingFilter
from rest_framework.permissions import AllowAny, IsAdminUser, IsAuthenticated, IsAuthenticatedOrReadOnly, BasePermission
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.pagination import PageNumberPagination
from rest_framework.views import APIView
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from user.models import User
from user.serializers import UserSerializer


# 把普通函数视图装饰城APIView视图, 就可以拥有认证,权限功能
@api_view(['GET'])
# @permission_classes((IsAuthenticated,))  # 默认配置,可不写, 可自定义
# @authentication_classes((JSONWebTokenAuthentication,))  # 默认配置,可不写 可自定义
def index(request):
    # 需要认证才能访问的函数视图
    return HttpResponse('函数视图')


class IndexView(View):
    # 普通类视图, 没有权限验证功能
    def get(self, request):
        return HttpResponse('类视图')


class ApiView(APIView):
    # APIView默认有认证,权限功能
    # authentication_classes = (JSONWebTokenAuthentication,)  # 默认配置,可不写, 可自定义
    # permission_classes = (IsAuthenticated,)  # 默认配置,可不写, 可自定义

    def get(self, request):
        return Response({"msg": "APIView"})


# def index(request):
#     # 需要认证才能访问的视图
#     return HttpResponse('hello')


# 自定义分页器 局部
class PageNum(PageNumberPagination):
    # 查询字符串中代表每页返回数据数量的参数名, 默认值: None
    page_size_query_param = 'page_size'
    # 查询字符串中代表页码的参数名, 有默认值: page
    # page_query_param = 'page'
    # 一页中最多的结果条数
    max_page_size = 2


class MyPermission(BasePermission):
    def has_permission(self, request, view):
        """判断用户对模型有没有访问权"""
        if request.user.is_superuser:
            # 管理员对用户模型有访问权
            return True
        elif view.kwargs.get('pk') == str(request.user.id):
            # 携带的id和用户的id相同时有访问权
            return True
        return False


# def has_object_permission(self, request, view, obj):
#     """获取单个数据时,判断用户对某个数据对象是否有访问权限"""
#     if request.user.id == obj.id:
#         return True
#     return False

class UserViewSet(viewsets.ModelViewSet):
    """
    完成产品的增删改查
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer  # 优先使用 get_serializer_class 返回的序列化器

    # 自定义认证类, 自定义会覆盖全局配置
    authentication_classes = (BasicAuthentication, SessionAuthentication)
    # 自定义权限类
    # permission_classes = (IsAdminUser, IsAuthenticated, IsAuthenticatedOrReadOnly, AllowAny)
    permission_classes = (MyPermission,)
    # 自定义限流类
    throttle_classes = [UserRateThrottle]

    # 指定过滤方法类, 排序方法类, 一个或多个
    filter_backends = (DjangoFilterBackend, OrderingFilter)  # 同时支持过滤和排序

    # 指定排序字段, 不设置, 排序功能不起效
    ordering_fields = ('date_joined', 'id')

    # 指定过滤字段, 不设置, 过滤功能不起效
    filter_fields = ('username', 'phone', 'is_active')

    # 自定义分页器 覆盖全局配置
    pagination_class = PageNum

    # 根据不同的请求, 获得不同的序列化器
    def get_serializer_class(self):
        # print(self.context)
        # if self.action == 'partial_update':
        #     return ProductPartialUpdateSerializer
        if self.action == 'unactived':
            return UserSerializer
        else:
            return UserSerializer

    @action(methods=['get'], detail=False)
    def unactived(self, request, *args, **kwargs):
        # 获取查询集, 过滤出未激活的用户
        qs = self.queryset.filter(is_active=False)
        # 使用序列化器, 序列化查询集, 并且是
        ser = self.get_serializer(qs, many=True)

        return Response(ser.data)


class RegistrView(APIView):
    """
       用户注册, 权限是: 匿名用户可访问
       """
    # 自定义权限类
    permission_classes = (AllowAny,)  # 所有的用户都可访问接口

    def post(self, request):
        '''
        :param request:  传递 email参数，password参数
        :return:返回注册成功
        '''
        username = request.data.get("username")
        code = request.data.get("code")
        password = request.data.get("password")
        phone = request.data.get("phone")
        if all([code, password, phone, username]):
            pass
        else:
            return Response({"code": 400, "msg": "参数不全"})

        redis_cli = get_redis_connection('verify_code')
        redis_bcode = redis_cli.get(phone)
        if redis_bcode:
            redis_bcode = redis_bcode.decode()
        if code != redis_bcode:
            return Response({"code": 400, "msg": "手机验证码错误"})

        user = User(username=username, phone=phone)  # 写入随机用户名
        user.set_password(password)
        user.save()
        return Response({"code": 200, "msg": "注册成功"})

    def str_name(self):
        '''
        创建自己的一个随机用户名
        :return:
        '''
        base = "syl"
        d = datetime.datetime.now()
        str_date = '%04d%02d%02d%02d%02d' % (d.year, d.month, d.day, d.hour, d.minute)
        str_randome = str(random.randint(10000, 99999))
        return base + str_date + str_randome


class Unique_test(APIView):
    permission_classes = (AllowAny,)

    def post(self, request):
        type = request.data.get("type")
        data = request.data.get("data")
        if not all([type, data]):
            return Response({"code": 400, 'msg': "参数不全，请重新输入"})
        if type == "username":
            count = User.objects.filter(username=data).count()
        if type == "phone":
            count = User.objects.filter(phone=data).count()
        if type == "email":
            count = User.objects.filter(email=data).count()
        return Response({"code": 200, "msg": "验证通过", "count": count})
